﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Linq;
using Flagwind.Data;
using Microsoft.VisualBasic;

namespace Flagwind.Utilities.DataBuilder.Controls
{
	public partial class Explorer : UserControl
	{
		#region 私有字段

		private TreeNode _rootNode;
		private bool _needRefresh;

		private IDataProvider _dataProvider;
		private string _dataProviderType;
		
		private string _currentDatabaseName;
		private string _currentConnectionString;
		private string _currentDatabaseNodePath;

		private readonly Dictionary<string, IDataProvider> _dataProviders = new Dictionary<string, IDataProvider>();
		private readonly Dictionary<string, string> _connectionStrings = new Dictionary<string, string>();

		private string _dbLeftChar = "[";
		private string _dbRightChar = "]";

		#endregion

		#region 私有常量

		private const string FILE_CONFIG = "Server.xml";

		private const string NODE_ROOT = "connections";
		private const string NODE_GROUP = "group";
		private const string NODE_GROUP_NAME = "name";

		private const string NODE_CONNECTION = "connection";
		private const string NODE_CONNECTION_NAME = "name";
		private const string NODE_CONNECTION_TYPE = "type";
		private const string NODE_CONNECTION_CONNECTION_STRING = "connectionString";
		private const string NODE_CONNECTION_PROVIDER = "provider";

		private const string IMG_ROOT = "Root";
		private const string IMG_FOLDER = "Folder";

		private const string IMG_CONNECTION_GROUP = "ConnectionGroup";
		private const string IMG_CONNECTION_ITEM = "ConnectionItem";

		private const string IMG_DATABASE = "DataBase";

		private const string IMG_TABLE_FOLDER = "TableFolder";
		private const string IMG_TABLE = "Table";
		private const string IMG_TABLE_COLUMN = "TableColumn";

		private const string IMG_VIEW_FOLDER = "ViewFolder";
		private const string IMG_VIEW = "View";
		private const string IMG_VIEW_COLUMN = "TableColumn";

		private const string IMG_PROCEDURE_FOLDER = "ProcedureFolder";
		private const string IMG_PROCEDURE = "Procedure";
		private const string IMG_PROCEDURE_PARAMETER = "ProcedureParameter";

		private const string IMG_FUNCTION_FOLDER = "FunctionFolder";
		private const string IMG_FUNCTION = "Function";
		private const string IMG_FUNCTION_PARAMETER = "FunctionParameter";

		#endregion

		#region 私有属性

		/// <summary>
		/// 数据访问提供程序。
		/// </summary>
		private IDataProvider DataProvider
		{
			get
			{
				if(this.treeView.SelectedNode != null)
				{
					string fullPath = this.treeView.SelectedNode.FullPath;

					foreach(var key in _dataProviders.Keys)
					{
						if(fullPath.IndexOf(key, StringComparison.OrdinalIgnoreCase) != -1)
						{
							this._dataProvider = this._dataProviders[key];
							this._currentConnectionString = this._connectionStrings[key];
							this._currentDatabaseNodePath = key;

							break;
						}
					}
				}

				Utility.DataProvider = _dataProvider;

				return _dataProvider;
			}
			set
			{
				this._dataProvider = value;
			}
		}

		#endregion

		#region 公共属性

		/// <summary>
		/// 获取或设置主容器。
		/// </summary>
		public IMasterContainer MasterContainer
		{
			get;
			private set;
		}

		#endregion

		#region 构造方法

		public Explorer(IMasterContainer masterContainer)
		{
			// 初始化组件
			InitializeComponent();

			this.MasterContainer = masterContainer;

			// 设置根节点
			_rootNode = this.treeView.Nodes[0];
		}

		#endregion

		#region 事件方法

		/// <summary>
		/// 资源管理器加载完成时调用。
		/// </summary>
		/// <param name="sender">事件发送者。</param>
		/// <param name="e">事件参数。</param>
		private void Explorer_Load(object sender, EventArgs e)
		{
			// 初始化图片列表
			this.InitImageList();

			// 初始化树菜单
			this.InitTreeView();
		}

		/// <summary>
		/// 资源管理器树菜单展开时调用。
		/// </summary>
		/// <param name="sender">事件发送者。</param>
		/// <param name="e">事件参数。</param>
		private void treeView_Expand(object sender, TreeViewEventArgs e)
		{
			// 设置鼠标为等待状态
			this.Cursor = Cursors.WaitCursor;

			// 设置选中的节点为当前展开的节点
			this.treeView.SelectedNode = e.Node;

			switch(e.Node.Level)
			{
				case 2:
				{
					// 加载连接
					this.LoadDatabase(e);

					break;
				}
				case 3:
				{
					// 加载主要数据
					this.LoadDataMaster(e);

					break;
				}
				case 5:
				{
					this.LoadDataDetail(e);

					break;
				}
			}

			this._needRefresh = false;

			// 还原鼠标为默认状态
			this.Cursor = Cursors.Default;
		}

		/// <summary>
		/// 树菜单点击时调用。
		/// </summary>
		/// <param name="sender">事件发送者。</param>
		/// <param name="e">事件参数。</param>
		private void treeView_MouseDown(object sender, MouseEventArgs e)
		{
			if(e.Button == MouseButtons.Right)
			{
				//确定右键的位置  
				Point clickPoint = new Point(e.X, e.Y);

				//在确定后的位置上面定义一个节点  
				TreeNode treeNode = this.treeView.GetNodeAt(clickPoint);

				if(treeNode != null)
				{
					//使treeview1的SelectedNode为当前新建的节点，也就是右键后的节点被选中  
					this.treeView.SelectedNode = treeNode;  
				}
			}
		}

		/// <summary>
		/// 右键菜单展开时调用。
		/// </summary>
		/// <param name="sender">事件发送者。</param>
		/// <param name="e">事件参数。</param>
		private void contextMenu_Opening(object sender, CancelEventArgs e)
		{
			if(this.treeView.SelectedNode != null)
			{
				var nodeTag = treeView.SelectedNode.Tag;

				tsmiAddGroup.Enabled = false;
				tsmiEditGroup.Enabled = false;
				tsmiDeleteGroup.Enabled = false;

				tsmiAddConnection.Enabled = false;
				tsmiDeleteConnection.Enabled = false;

				tsmiCreateEntity.Enabled = false;

				switch(this.treeView.SelectedNode.Level)
				{
					// 根节点
					case 0:
					{
						tsmiAddGroup.Enabled = true;

						break;
					}
					// 连接组节点
					case 1:
					{
						tsmiAddGroup.Enabled = true;
						tsmiEditGroup.Enabled = true;
						tsmiDeleteGroup.Enabled = true;
						tsmiAddConnection.Enabled = true;

						break;
					}
					// 连接节点
					case 2:
					{
						tsmiDeleteConnection.Enabled = true;

						break;
					}
					// 表/视图组
					case 4:
					{
						if(nodeTag.Equals("tables") || nodeTag.Equals("views"))
						{
							tsmiCreateEntity.Enabled = true;
						}

						break;
					}
					// 表/视图项
					case 5:
					{
						if(nodeTag.Equals("table") || nodeTag.Equals("view"))
						{
							tsmiCreateEntity.Enabled = true;
						}

						break;
					}
				}
			}
		}

		/// <summary>
		/// 新建分组菜单项点击时调用。
		/// </summary>
		/// <param name="sender">事件发送者。</param>
		/// <param name="e">事件参数。</param>
		private void tsmiAddGroup_Click(object sender, EventArgs e)
		{
			// 获取分组名称
			string groupName = Microsoft.VisualBasic.Interaction.InputBox("请输入新建的分组名称：", "分组管理", "新建分组1");

			if(string.IsNullOrWhiteSpace(groupName))
				return;

			// 实例化 XML 文档对象
			var document = new XmlDocument();

			// 加载 XML 文档
			document.Load(FILE_CONFIG);

			// 获取根节点
			var rootNode = document.GetElementsByTagName(NODE_ROOT)[0];

			// 新建 gorup 节点
			var groupNode = document.CreateElement(NODE_GROUP);
			groupNode.SetAttribute(NODE_GROUP_NAME, groupName);

			// 追加至文档
			rootNode.AppendChild(groupNode);

			// 保存文档
			document.Save(FILE_CONFIG);

			// 重新加载树节点
			this.InitTreeView();
		}

		/// <summary>
		/// 修改分组菜单项点击时调用。
		/// </summary>
		/// <param name="sender">事件发送者。</param>
		/// <param name="e">事件参数。</param>
		private void tsmiEditGroup_Click(object sender, EventArgs e)
		{
			var groupName = this.treeView.SelectedNode.Text;

			// 实例化 XML 文档对象
			var document = new XmlDocument();

			// 加载 XML 文档
			document.Load(FILE_CONFIG);

			var groupNodes = document.GetElementsByTagName(NODE_GROUP);

			var groupNode = groupNodes.Cast<XmlElement>().FirstOrDefault(node => node.Attributes[NODE_GROUP_NAME].Value.Equals(groupName));

			if(groupNode == null)
				return;

			// 获取分组名称
			string newGroupName = Microsoft.VisualBasic.Interaction.InputBox("请输入新建的分组名称：", "分组管理", groupName);

			if(!string.IsNullOrWhiteSpace(newGroupName) && !groupName.Equals(newGroupName))
			{
				groupNode.SetAttribute(NODE_GROUP_NAME, newGroupName);

				// 保存文档
				document.Save(FILE_CONFIG);

				// 重新加载树节点
				this.InitTreeView();
			}
		}

		/// <summary>
		/// 删除分组菜单项点击时调用。
		/// </summary>
		/// <param name="sender">事件发送者。</param>
		/// <param name="e">事件参数。</param>
		private void tsmiDeleteGroup_Click(object sender, EventArgs e)
		{
			var groupName = this.treeView.SelectedNode.Text;

			// 实例化 XML 文档对象
			var document = new XmlDocument();

			// 加载 XML 文档
			document.Load(FILE_CONFIG);

			var groupNodes = document.GetElementsByTagName(NODE_GROUP);

			var groupNode = groupNodes.Cast<XmlElement>().FirstOrDefault(node => node.Attributes[NODE_GROUP_NAME].Value.Equals(groupName));

			if(groupNode == null)
				return;

			var result = MessageBox.Show("请确认是否删除分组 [" + groupName + "] ？", "分组管理", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning);

			if(result == DialogResult.OK)
			{
				groupNode.ParentNode.RemoveChild(groupNode);

				// 保存文档
				document.Save(FILE_CONFIG);

				// 重新加载树节点
				this.InitTreeView();
			}
		}

		/// <summary>
		/// 刷新菜单项点击时调用。
		/// </summary>
		/// <param name="sender">事件发送者。</param>
		/// <param name="e">事件参数。</param>
		private void tsmiRefresh_Click(object sender, EventArgs e)
		{
			this._needRefresh = true;

			// 获取选中的节点
			var selectedNode = this.treeView.SelectedNode;

			if(selectedNode != null)
			{
				switch(selectedNode.Level)
				{
					case 4:
					case 6:
					{
						// 记住当前节点是否为展开状态
						var isExpanded = selectedNode.IsExpanded;

						selectedNode.Parent.Collapse();
						selectedNode.Parent.Expand();

						this.treeView.SelectedNode = selectedNode;

						if(isExpanded)
						{
							selectedNode.Collapse();
							selectedNode.Expand();
						}

						break;
					}
					default:
					{
						if(selectedNode.IsExpanded)
						{
							selectedNode.Collapse();
							selectedNode.Expand();
						}

						break;
					}
				}
			}
		}

		/// <summary>
		/// 添加连接菜单项点击时调用。
		/// </summary>
		/// <param name="sender">事件发送者。</param>
		/// <param name="e">事件参数。</param>
		private void tsmiAddConnection_Click(object sender, EventArgs e)
		{
			if(this.treeView.SelectedNode != null && this.treeView.SelectedNode.Level == 1)
			{
				string groupName = this.treeView.SelectedNode.Text;

				// 显示连接窗体
				var frmWizard = new FDbConnectionWizard();

				frmWizard.ShowDialog();

				if(!string.IsNullOrEmpty(frmWizard.ConnectionString) && !string.IsNullOrEmpty(frmWizard.ServerName))
				{
					// 实例化 XML 文档对象
					var document = new XmlDocument();

					// 加载 XML 文档
					document.Load(FILE_CONFIG);

					var groupNodes = document.GetElementsByTagName(NODE_GROUP);

					var groupNode = groupNodes.Cast<XmlElement>().FirstOrDefault(node => node.Attributes[NODE_GROUP_NAME].Value.Equals(groupName));

					if(groupNode != null)
					{
						string serverName = string.Empty;
						string providerType = frmWizard.ProviderType.ToString();

						if(frmWizard.ProviderType == DataProviderType.UNKNOWN)
						{
							providerType = Interaction.InputBox("请输入数据库类型(注意大小写)。\r\n系统支持的类型有：Access,SqlServer,Oracle,DB2,Sysbase,MySql,SQLite,UNKNOWN", "数据连接管理", "", -1, -1);

							if(providerType == "SQLite")
							{
								serverName = "main";
							}
							else
							{
								serverName = Interaction.InputBox("请输入 服务器/连接 的名称", "数据连接管理", "", -1, -1);
							}
						}
						else
						{
							serverName = frmWizard.ServerName;
						}

						var connectionNode = document.CreateElement(NODE_CONNECTION);
						connectionNode.SetAttribute(NODE_CONNECTION_NAME, serverName);
						connectionNode.SetAttribute(NODE_CONNECTION_TYPE, providerType);
						connectionNode.SetAttribute(NODE_CONNECTION_CONNECTION_STRING, frmWizard.ConnectionString);
						connectionNode.SetAttribute(NODE_CONNECTION_PROVIDER, frmWizard.Provider);

						groupNode.AppendChild(connectionNode);

						document.Save(FILE_CONFIG);

						// 重新加载树节点
						this.InitTreeView();
					}
					else
					{
						//MessageBox.Show("连接字符串为空，请在[新建连接窗体]中单击[高级选项]查看或者设置！");
					}
				}
			}
		}

		/// <summary>
		/// 删除连接菜单项点击时调用。
		/// </summary>
		/// <param name="sender">事件发送者。</param>
		/// <param name="e">事件参数。</param>
		private void tsmiDeleteConnection_Click(object sender, EventArgs e)
		{
			if(this.treeView.SelectedNode.Level == 2)
			{
				var groupName = this.treeView.SelectedNode.Parent.Text;
				var nodeName = ((ConnectionNode)this.treeView.SelectedNode.Tag).Name;

				// 实例化 XML 文档对象
				var document = new XmlDocument();

				// 加载 XML 文档
				document.Load(FILE_CONFIG);

				// 获取分组节点
				var groupNode = document.GetElementsByTagName(NODE_GROUP).Cast<XmlElement>().FirstOrDefault(node => node.Attributes[NODE_GROUP_NAME].Value.Equals(groupName));

				// 获取连接节点
				var itemNode = groupNode.ChildNodes.Cast<XmlElement>().FirstOrDefault(node => node.Attributes[NODE_CONNECTION_NAME].Value.Equals(nodeName));

				var result = MessageBox.Show("确认删除当前连接[0]吗？", "数据连接管理", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation);

				if(itemNode != null && result == DialogResult.OK)
				{
					groupNode.RemoveChild(itemNode);

					document.Save(FILE_CONFIG);

					this.InitTreeView();
				}
			}
		}

		/// <summary>
		/// 点击生成实体菜单时调用。
		/// </summary>
		/// <param name="sender">事件发送者。</param>
		/// <param name="e">事件参数。</param>
		private void tsmiCreateEntity_Click(object sender, EventArgs e)
		{
			this.GenerateEntity();
		}

		#endregion

		#region 公共方法

		/// <summary>
		/// 生成实体。
		/// </summary>
		public void GenerateEntity()
		{
			var tables = new List<string>();
			var views = new List<string>();
			var selectedNode = this.treeView.SelectedNode;
			var databaseName = string.Empty;

			if(selectedNode != null)
			{
				// 选中单表或单视图
				if(selectedNode.Nodes.Count > 0 && selectedNode.FirstNode.Text == "列")
				{
					// 当前节点是表或者视图名称
					var name = selectedNode.Text;

					// 表
					if(selectedNode.FirstNode.Name == "table_column")
					{
						tables.Add(name);
					}
					// 视图
					else
					{
						views.Add(name);
					}

					databaseName = selectedNode.Parent.Parent.Name;
				}
				// 选中表
				else if(selectedNode.Text == "表")
				{
					tables.AddRange(from TreeNode node in selectedNode.Nodes select node.Text);

					databaseName = selectedNode.Parent.Name;
				}
				// 选中视图
				else if(selectedNode.Text == "视图")
				{
					views.AddRange(from TreeNode node in selectedNode.Nodes select node.Text);

					databaseName = selectedNode.Parent.Name;
				}

				var builder = new EntityBuilder(this.DataProvider, databaseName, tables, views);

				this.MasterContainer.OpenPanel(this, builder);
			}
		}

		#endregion

		#region 私有方法

		/// <summary>
		/// 初始化树菜单。
		/// </summary>
		private void InitTreeView()
		{
			// 清除根节点以下的子所有节点
			this._rootNode.Nodes.Clear();

			// 实例化 XML 文档对象
			var document = new XmlDocument();

			// 加载 XML 文档
			document.Load(FILE_CONFIG);

			// 获取所有连接分组
			var groups = document.GetElementsByTagName(NODE_GROUP);

			foreach(XmlNode group in groups)
			{
				var groupName = group.Attributes[NODE_GROUP_NAME].Value;
				var groupNode = this._rootNode.Nodes.Add(groupName);

				// 设置分组节点图标
				groupNode.ImageKey = IMG_CONNECTION_GROUP;
				groupNode.SelectedImageKey = IMG_CONNECTION_GROUP;

				foreach(XmlNode item in group.ChildNodes)
				{
					if(item.Name.Equals(NODE_CONNECTION))
					{
						var itemTag = new ConnectionNode
						{
							Name = item.Attributes[NODE_CONNECTION_NAME].Value,
							Type = item.Attributes[NODE_CONNECTION_TYPE].Value,
							ConnectionString = item.Attributes[NODE_CONNECTION_CONNECTION_STRING].Value,
							Provider = item.Attributes[NODE_CONNECTION_PROVIDER] != null && !string.IsNullOrWhiteSpace(item.Attributes[NODE_CONNECTION_PROVIDER].Value) ? item.Attributes[NODE_CONNECTION_PROVIDER].Value : item.Attributes[NODE_CONNECTION_TYPE].Value
						};

						// 设置连接节点
						var itemNode = new TreeNode
						{
							ImageKey = IMG_CONNECTION_ITEM,
							SelectedImageKey = IMG_CONNECTION_ITEM,
							Name = itemTag.Name,
							Text = string.Format("{0}:{1}", itemTag.Type, itemTag.Name),
							Tag = itemTag
						};

						// 将连接节点添加止分组节点中
						itemNode.Nodes.Add(new TreeNode());
						groupNode.Nodes.Add(itemNode);
						groupNode.Expand();
					}
				}
			}

			this._rootNode.Expand();
		}

		/// <summary>
		/// 加载图片列表。
		/// </summary>
		private void InitImageList()
		{
			this.imageList.Images.Add(IMG_ROOT, this.LoadImageFile(@".\Images\root.png"));
			this.imageList.Images.Add(IMG_FOLDER, this.LoadImageFile(@".\Images\folder.png"));

			this.imageList.Images.Add(IMG_CONNECTION_GROUP, this.LoadImageFile(@".\Images\connection_group.png"));
			this.imageList.Images.Add(IMG_CONNECTION_ITEM, this.LoadImageFile(@".\Images\connection_item.png"));
			this.imageList.Images.Add(IMG_DATABASE, this.LoadImageFile(@".\Images\database.png"));
			
			this.imageList.Images.Add(IMG_TABLE_FOLDER, this.LoadImageFile(@".\Images\table_folder.png"));
			this.imageList.Images.Add(IMG_TABLE, this.LoadImageFile(@".\Images\table.png"));
			this.imageList.Images.Add(IMG_TABLE_COLUMN, this.LoadImageFile(@".\Images\table_column.png"));

			this.imageList.Images.Add(IMG_VIEW_FOLDER, this.LoadImageFile(@".\Images\view_folder.png"));
			this.imageList.Images.Add(IMG_VIEW, this.LoadImageFile(@".\Images\view.png"));

			this.imageList.Images.Add(IMG_PROCEDURE_FOLDER, this.LoadImageFile(@".\Images\procedure_folder.png"));
			this.imageList.Images.Add(IMG_PROCEDURE, this.LoadImageFile(@".\Images\procedure.png"));
			this.imageList.Images.Add(IMG_PROCEDURE_PARAMETER, this.LoadImageFile(@".\Images\procedure_parameter.png"));

			this.imageList.Images.Add(IMG_FUNCTION_FOLDER, this.LoadImageFile(@".\Images\function_folder.png"));
			this.imageList.Images.Add(IMG_FUNCTION, this.LoadImageFile(@".\Images\function.png"));
			this.imageList.Images.Add(IMG_FUNCTION_PARAMETER, this.LoadImageFile(@".\Images\function_parameter.png"));

			// 设置根节点
			this._rootNode.ImageKey = IMG_ROOT;
			this._rootNode.SelectedImageKey = IMG_ROOT;

			this.treeView.ImageList = this.imageList;
		}

		/// <summary>
		/// 加载图像文件。
		/// </summary>
		/// <returns></returns>
		private Image LoadImageFile(string fileName)
		{
			Bitmap bitmap;

			using(var image = Image.FromFile(fileName))
			{
				bitmap = new Bitmap(image);

				bitmap.MakeTransparent();
			}

			return bitmap;
		}

		/// <summary>
		/// 加载数据库。
		/// </summary>
		private void LoadDatabase(TreeViewEventArgs e)
		{
			if(!string.IsNullOrEmpty(e.Node.FirstNode.Text) && !this._needRefresh)
				return;

			// 填充表/视图等节点
			var connection = e.Node.Tag as ConnectionNode;

			// 获取数据访问提供者
			_dataProvider = DataProviderFactory.GetProvider(connection.Provider, connection.ConnectionString);
			_dataProviderType = connection.Type.ToLower();

			// 将当前数据访问提供程序加入到路径缓存中
			_dataProviders[e.Node.FullPath] = _dataProvider;
			_connectionStrings[e.Node.FullPath] = connection.ConnectionString;

			// 设置数据库连接字符
			this.SetDbChar();

			try
			{
				var schema = _dataProvider.GetSchema("Databases", null);
				var databaseView = schema.DefaultView;

				if(schema.Columns.Contains("dbid"))
					databaseView.Sort = "dbid";

				// 清除所有子节点
				e.Node.Nodes.Clear();

				foreach(DataRowView row in databaseView)
				{
					// 创建数据库节点
					var dataBaseNode = new TreeNode(row["database_name"].ToString())
					{
						ImageKey = IMG_DATABASE,
						SelectedImageKey = IMG_DATABASE,
						Name = row["database_name"].ToString()
					};

					// 添加数据库节点
					e.Node.Nodes.Add(dataBaseNode);

					dataBaseNode.Nodes.Add(new TreeNode("表")
					{
						Name = "table",
						ImageKey = IMG_TABLE_FOLDER,
						SelectedImageKey = IMG_TABLE_FOLDER,
						Tag = "tables"
					});

					dataBaseNode.Nodes.Add(new TreeNode("视图")
					{
						Name = "view",
						ImageKey = IMG_VIEW_FOLDER,
						SelectedImageKey = IMG_VIEW_FOLDER,
						Tag = "views"
					});

					dataBaseNode.Nodes.Add(new TreeNode("存储过程")
					{
						Name = "procedure",
						ImageKey = IMG_PROCEDURE_FOLDER,
						SelectedImageKey = IMG_PROCEDURE_FOLDER,
						Tag = "procedures"
					});

					dataBaseNode.Nodes.Add(new TreeNode("函数")
					{
						Name = "function",
						ImageKey = IMG_FUNCTION_FOLDER,
						SelectedImageKey = IMG_FUNCTION_FOLDER,
						Tag = "functions"
					});
				}
			}
			catch(Exception ex)
			{
				//可能有些数据库不支持 Databases 元数据
				if(this._dataProviderType.Equals("oracle"))
				{
					// 创建数据库节点
					var dataBaseNode = new TreeNode("数据库")
					{
						ImageKey = IMG_DATABASE,
						SelectedImageKey = IMG_DATABASE,
						Name = "main"
					};

					// 添加数据库节点
					e.Node.Nodes.Add(dataBaseNode);

					dataBaseNode.Nodes.Add(new TreeNode("表")
					{
						Name = "table",
						ImageKey = IMG_TABLE_FOLDER,
						SelectedImageKey = IMG_TABLE_FOLDER,
						Tag = "tables"
					});

					dataBaseNode.Nodes.Add(new TreeNode("视图")
					{
						Name = "view",
						ImageKey = IMG_VIEW_FOLDER,
						SelectedImageKey = IMG_VIEW_FOLDER,
						Tag = "views"
					});
				}
				else if(this._dataProviderType.Equals("sqlite") || this._dataProviderType.Equals("access"))
				{
					// 创建数据库节点
					var dataBaseNode = new TreeNode("数据库")
					{
						ImageKey = IMG_DATABASE,
						SelectedImageKey = IMG_DATABASE,
						Name = "main"
					};

					// 添加数据库节点
					e.Node.Nodes.Add(dataBaseNode);

					dataBaseNode.Nodes.Add(new TreeNode("表")
					{
						Name = "table",
						ImageKey = IMG_TABLE_FOLDER,
						SelectedImageKey = IMG_TABLE_FOLDER,
						Tag = "tables"
					});

					dataBaseNode.Nodes.Add(new TreeNode("视图")
					{
						Name = "view",
						ImageKey = IMG_VIEW_FOLDER,
						SelectedImageKey = IMG_VIEW_FOLDER,
						Tag = "views"
					});
				}
				else if(this._dataProviderType.Equals("sqlserverce"))
				{
					// 创建数据库节点
					var dataBaseNode = new TreeNode("数据库")
					{
						ImageKey = IMG_DATABASE,
						SelectedImageKey = IMG_DATABASE,
						Name = ""
					};

					// 添加数据库节点
					e.Node.Nodes.Add(dataBaseNode);

					dataBaseNode.Nodes.Add(new TreeNode("表")
					{
						Name = "table",
						ImageKey = IMG_VIEW_FOLDER,
						SelectedImageKey = IMG_VIEW_FOLDER,
						Tag = "tables"
					});
				}
			}
		}

		/// <summary>
		/// 加载主要数据。
		/// </summary>
		/// <param name="e"></param>
		private void LoadDataMaster(TreeViewEventArgs e)
		{
			// 获取数据库节点
			var databaseNode = e.Node;

			// 当前数据库名称
			this._currentDatabaseName = databaseNode.Name;

			if(this.DataProvider.ProviderType == DataProviderType.SqlServer || this.DataProvider.ProviderType == DataProviderType.MySql || this.DataProvider.ProviderType == DataProviderType.PostgreSQL)
			{
				this.DataProvider.ConnectionString = this._currentConnectionString + ";DataBase=" + databaseNode.Name;
			}

			// 获取表节点
			var tableNode = databaseNode.FirstNode;

			if(tableNode.Nodes.Count == 0 || this._needRefresh)
			{
				string databaseName = databaseNode.Name;
				
				DataTable schemaTable;

				#region 显示表

				string tableFilter = "BASE TABLE";

				if(this._dataProviderType == "sqlite")
				{
					tableFilter = "table";
				}
				if(this._dataProviderType == "sqlserverce")
				{
					databaseName = null;
					tableFilter = "TABLE";
				}
				if(this._dataProviderType == "access")
				{
					databaseName = null;
					tableFilter = "TABLE";
				}

				if(this.DataProvider.ProviderType == DataProviderType.MySql)
				{
					schemaTable = this.DataProvider.GetSchema("Tables", new string[] { null, databaseName, null, tableFilter });
				}
				else if(this.DataProvider.ProviderType == DataProviderType.Oracle)
				{
					schemaTable = this.DataProvider.GetSchema("Tables", null);
				}
				else
				{
					schemaTable = this.DataProvider.GetSchema("Tables", new string[] { databaseName, null, null, tableFilter });
				}

				// 数据表视图
				DataView tableView = schemaTable.DefaultView;

				// 清除“表”节点下的所有子节点
				tableNode.Nodes.Clear();

				if(this.DataProvider.ProviderType == DataProviderType.Oracle)
				{
					string connectionUserId = this.DataProvider.ConnectionUserId;
					DataView oracleTableView = new DataView(schemaTable, "OWNER='" + connectionUserId + "'", "table_name", DataViewRowState.CurrentRows);

					foreach(DataRowView dataRowView in oracleTableView)
					{
						// 表
						var childNode = new TreeNode(dataRowView[1].ToString())
						{
							Name = dataRowView[1].ToString(),
							ImageKey = IMG_TABLE,
							SelectedImageKey = IMG_TABLE,
							Tag = "table"
						};

						childNode.Nodes.Add(new TreeNode("列")
						{
							Name = "table_column",
							ImageKey = IMG_FOLDER,
							SelectedImageKey = IMG_FOLDER
						});

						childNode.Nodes.Add(new TreeNode("索引")
						{
							ImageKey = IMG_FOLDER,
							SelectedImageKey = IMG_FOLDER
						});

						childNode.Nodes.Add(new TreeNode("调用器")
						{
							ImageKey = IMG_FOLDER,
							SelectedImageKey = IMG_FOLDER
						});

						tableNode.Nodes.Add(childNode);
					}
				}
				else
				{
					tableView.Sort = "table_schema, table_name";

					foreach(DataRowView dataRowView in tableView)
					{
						// 视图
						var childNode = new TreeNode(dataRowView[1].ToString() + "." + dataRowView[2])
						{
							Name = dataRowView[2].ToString(),
							ImageKey = IMG_TABLE,
							SelectedImageKey = IMG_TABLE,
							Tag = "view"
						};

						childNode.Nodes.Add(new TreeNode("列")
						{
							Name = "table_column",
							ImageKey = IMG_FOLDER,
							SelectedImageKey = IMG_FOLDER
						});

						childNode.Nodes.Add(new TreeNode("索引")
						{
							ImageKey = IMG_FOLDER,
							SelectedImageKey = IMG_FOLDER
						});

						childNode.Nodes.Add(new TreeNode("调用器")
						{
							ImageKey = IMG_FOLDER,
							SelectedImageKey = IMG_FOLDER
						});

						tableNode.Nodes.Add(childNode);
					}
				}

				#endregion

				// SQLCE 不支持视图、存储过程
				if(this._dataProviderType != "sqlserverce")
				{
					#region 显示视图

					var viewNode = databaseNode.Nodes[1];
					schemaTable = this.DataProvider.GetSchema("Views", null);
					var viewView = schemaTable.DefaultView;

					viewNode.Nodes.Clear();

					if(this.DataProvider.ProviderType == DataProviderType.Oracle)
					{
						var connectionUserId = this.DataProvider.ConnectionUserId;
						var oracleViewView = new DataView(schemaTable, "OWNER='" + connectionUserId + "'", "owner,view_name", DataViewRowState.CurrentRows);

						foreach(DataRowView dataRowView in oracleViewView)
						{
							var childNode = new TreeNode(dataRowView[0] + "." + dataRowView[1])
							{
								Name = dataRowView[1].ToString(),
								ImageKey = IMG_VIEW,
								SelectedImageKey = IMG_VIEW,
								Tag = "view"
							};

							childNode.Nodes.Add(new TreeNode("列")
							{
								Name = "view_column",
								ImageKey = IMG_FOLDER,
								SelectedImageKey = IMG_FOLDER
							});

							childNode.Nodes.Add(new TreeNode("源表列")
							{
								Name = "view_original_column",
								ImageKey = IMG_FOLDER,
								SelectedImageKey = IMG_FOLDER
							});

							viewNode.Nodes.Add(childNode);
						}
					}
					else
					{
						viewView.Sort = "table_schema, table_name";

						foreach(DataRowView dataRowView in viewView)
						{
							var childNode = new TreeNode(dataRowView[1] + "." + dataRowView[2])
							{
								Name = dataRowView[2].ToString(),
								ImageKey = IMG_VIEW,
								SelectedImageKey = IMG_VIEW,
								Tag = "view"
							};

							childNode.Nodes.Add(new TreeNode("列")
							{
								Name = "view_column",
								ImageKey = IMG_FOLDER,
								SelectedImageKey = IMG_FOLDER
							});

							childNode.Nodes.Add(new TreeNode("源表列")
							{
								Name = "view_original_column",
								ImageKey = IMG_FOLDER,
								SelectedImageKey = IMG_FOLDER
							});

							viewNode.Nodes.Add(childNode);
						}
					}

					#endregion

					// 有些数据库没有存储过程
					if(databaseNode.Nodes.Count >= 3)
					{
						// PostgreSQL 没有单独的存储过程，统一成为函数
						if(this.DataProvider.ProviderType != DataProviderType.PostgreSQL)
						{
							#region 显示存储过程

							var procedureNode = databaseNode.Nodes[2];
							schemaTable = this.DataProvider.GetSchema("Procedures", new string[]
							{
								databaseNode.Name, null, null
							});
							var procdureView = schemaTable.DefaultView;
							procdureView.RowFilter = "ROUTINE_TYPE='PROCEDURE'";
							procdureView.Sort = "ROUTINE_NAME";

							procedureNode.Nodes.Clear();

							foreach(DataRowView dataRowView in procdureView)
							{
								var childNode = new TreeNode(dataRowView["ROUTINE_SCHEMA"] + "." + dataRowView["ROUTINE_NAME"])
								{
									Name = dataRowView["ROUTINE_NAME"].ToString(),
									ImageKey = IMG_PROCEDURE,
									SelectedImageKey = IMG_PROCEDURE,
									Tag = "procedure"
								};

								childNode.Nodes.Add(new TreeNode("参数")
								{
									Name = "procdure_parameter",
									ImageKey = IMG_FOLDER,
									SelectedImageKey = IMG_FOLDER
								});

								procedureNode.Nodes.Add(childNode);
							}

							#endregion

							#region 显示函数

							var functionNode = databaseNode.Nodes[3];
							var functionView = schemaTable.DefaultView;
							functionView.RowFilter = "ROUTINE_TYPE='FUNCTION'";
							functionView.Sort = "ROUTINE_NAME";

							functionNode.Nodes.Clear();

							foreach(DataRowView dataRowView in functionView)
							{
								var childNode = new TreeNode(dataRowView["ROUTINE_SCHEMA"] + "." + dataRowView["ROUTINE_NAME"])
								{
									Name = dataRowView["ROUTINE_NAME"].ToString(),
									ImageKey = IMG_FUNCTION,
									SelectedImageKey = IMG_FUNCTION,
									Tag = "function"
								};

								childNode.Nodes.Add(new TreeNode("参数")
								{
									Name = "function_parameter",
									ImageKey = IMG_FOLDER,
									SelectedImageKey = IMG_FOLDER
								});

								childNode.Nodes.Add(new TreeNode("返回结果")
								{
									ImageKey = IMG_FOLDER,
									SelectedImageKey = IMG_FOLDER
								});

								functionNode.Nodes.Add(childNode);
							}

							#endregion
						}
						else
						{
							#region 显示 PostgreSQL 函数

							schemaTable = this.DataProvider.GetSchema("Procedures", null);
							var functionNode = databaseNode.Nodes[3];
							var functionView = schemaTable.DefaultView;
							functionView.Sort = "ROUTINE_NAME";

							functionNode.Nodes.Clear();

							foreach(DataRowView dataRowView in functionView)
							{
								var childNode = new TreeNode(dataRowView["ROUTINE_NAME"].ToString())
								{
									Name = dataRowView["ROUTINE_NAME"].ToString(),
									ImageKey = IMG_FUNCTION,
									SelectedImageKey = IMG_FUNCTION,
									Tag = "function"
								};

								childNode.Nodes.Add(new TreeNode("参数")
								{
									Name = "function_parameter",
									ImageKey = IMG_FOLDER,
									SelectedImageKey = IMG_FOLDER
								});

								childNode.Nodes.Add(new TreeNode("返回结果")
								{
									ImageKey = IMG_FOLDER,
									SelectedImageKey = IMG_FOLDER
								});

								functionNode.Nodes.Add(childNode);
							}

							#endregion
						}
					}

				}
			}
		}

		/// <summary>
		/// 加载数据明细。
		/// </summary>
		/// <param name="e">事件参数对象。</param>
		private void LoadDataDetail(TreeViewEventArgs e)
		{
			if(e.Node.Nodes.Count > 0)
			{
				#region 加载表列

				if(e.Node.FirstNode.Name.Equals("table_column"))
				{
					var tableNode = e.Node;
					var columnsNode = tableNode.FirstNode;

					if(columnsNode.Nodes.Count <= 0 || this._needRefresh)
					{
						// 清除原有节点
						columnsNode.Nodes.Clear();

						DataTable columnsTable;
						DataView columnsView;
						string tableName = tableNode.Name;

						// 处理 Access 
						if(this._dataProviderType.Equals("access"))
						{
							columnsTable = this.DataProvider.GetSchema("Columns", new string[]{null, null, tableName});
							columnsView = columnsTable.DefaultView;
							columnsView.Sort = "ordinal_position";

							var dataTypeSchemaTable = this.DataProvider.GetSchema("DataTypes", null);
							var dataTypeNames = new Dictionary<string, string>();
							var index = dataTypeSchemaTable.Columns.Count - 1;

							foreach(DataRow dataRow in dataTypeSchemaTable.Rows)
							{
								string key = dataRow[index].ToString();

								if(!dataTypeNames.ContainsKey(key))
								{
									dataTypeNames.Add(key, dataRow[0].ToString());
								}
							}

							foreach(DataRowView dataRowView in columnsView)
							{
								string text = dataRowView["COLUMN_NAME"] + " [" + dataTypeNames[dataRowView["DATA_TYPE"].ToString()];

								if(dataRowView["CHARACTER_MAXIMUM_LENGTH"] != DBNull.Value)
								{
									long length = Convert.ToInt64(dataRowView["CHARACTER_MAXIMUM_LENGTH"]);

									if(length > 0 && length <= 255)
									{
										text = dataRowView["COLUMN_NAME"] + "[VarChar";
									}

									text = text + "(" + length + ")]";
								}
								else
								{
									text = text + "]";
								}

								var childNode = new TreeNode(text)
								{
									Name = dataRowView["COLUMN_NAME"].ToString(),
									ImageKey = IMG_TABLE_COLUMN,
									SelectedImageKey = IMG_TABLE_COLUMN
								};

								columnsNode.Nodes.Add(childNode);
							}
						}
						// 处理 oracle
						else if(this._dataProviderType.Equals("oracle"))
						{
							columnsTable = this.DataProvider.GetSchema("Columns", new string[]
							{
								this.DataProvider.ConnectionUserId, tableName
							});

							columnsView = columnsTable.DefaultView;
							columnsView.Sort = "column_name";

							foreach(DataRowView dataRowView in columnsView)
							{
								string text = dataRowView["COLUMN_NAME"] + " [" + dataRowView["DATATYPE"];

								if(dataRowView["length"] != DBNull.Value)
								{
									text = text + "(" + dataRowView["length"] + ")]";
								}
								else
								{
									text = text + "]";
								}

								var childNode = new TreeNode(text)
								{
									Name = dataRowView["COLUMN_NAME"].ToString(), ImageKey = IMG_TABLE_COLUMN, SelectedImageKey = IMG_TABLE_COLUMN
								};

								columnsNode.Nodes.Add(childNode);
							}
						}
						else
						{
							columnsTable = this.DataProvider.GetSchema("Columns", new string[]
							{
								null, null, tableName
							});

							columnsView = columnsTable.DefaultView;
							columnsView.Sort = "ordinal_position";

							foreach(DataRowView dataRowView in columnsView)
							{
								string text = dataRowView["COLUMN_NAME"] + " [" + dataRowView["DATA_TYPE"];

								if(dataRowView["CHARACTER_MAXIMUM_LENGTH"] != DBNull.Value)
								{
									text = text + "(" + dataRowView["CHARACTER_MAXIMUM_LENGTH"] + ")]";
								}
								else
								{
									text = text + "]";
								}

								var childNode = new TreeNode(text)
								{
									Name = dataRowView["COLUMN_NAME"].ToString(),
									ImageKey = IMG_TABLE_COLUMN,
									SelectedImageKey = IMG_TABLE_COLUMN
								};

								columnsNode.Nodes.Add(childNode);
							}
						}
					}
				}

				#endregion

				#region 加载视图列

				if(e.Node.FirstNode.Name.Equals("view_column"))
				{
					var viewNode = e.Node;
					var columnsNode = viewNode.FirstNode;

					if(columnsNode.Nodes.Count <= 0 || this._needRefresh)
					{
						#region 视图列

						// 清除原有节点
						columnsNode.Nodes.Clear();

						string viewName = viewNode.Name;
						DataTable columnsTable = this.DataProvider.GetSchema("Columns", new string[] { null, null, viewName });
						DataView columnsView = columnsTable.DefaultView;
						columnsView.Sort = "COLUMN_NAME";

						foreach(DataRowView dataRowView in columnsView)
						{
							string text = dataRowView["TABLE_SCHEMA"] + "." + dataRowView["TABLE_NAME"] + "." + dataRowView["COLUMN_NAME"];

							var childNode = new TreeNode(text)
							{
								Name = dataRowView["COLUMN_NAME"].ToString(),
								ImageKey = IMG_VIEW_COLUMN,
								SelectedImageKey = IMG_VIEW_COLUMN
							};

							columnsNode.Nodes.Add(childNode);
						}

						#endregion

						#region 原始视图列

						var originalColumnsNode = viewNode.Nodes[1];
						originalColumnsNode.Nodes.Clear();

						// 对于视图，使用Columns 获取视图的列，ViewColumns 获取的则是各表的原始列
						columnsTable = this.DataProvider.GetSchema("ViewColumns", new string[] { null, null, viewName });
						columnsView = columnsTable.DefaultView;
						columnsView.Sort = "COLUMN_NAME";

						foreach(DataRowView dataRowView in columnsView)
						{
							string text = dataRowView["TABLE_SCHEMA"] + "." + dataRowView["TABLE_NAME"] + "." + dataRowView["COLUMN_NAME"];

							var childNode = new TreeNode(text)
							{
								Name = dataRowView["COLUMN_NAME"].ToString(),
								ImageKey = IMG_VIEW_COLUMN,
								SelectedImageKey = IMG_VIEW_COLUMN
							};

							originalColumnsNode.Nodes.Add(childNode);
						}

						#endregion
					}
				}

				#endregion

				#region 存储过程参数

				if(e.Node.FirstNode.Name.Equals("procdure_parameter"))
				{
					var procdureNode = e.Node;
					var parametersNode = procdureNode.FirstNode;

					if(parametersNode.Nodes.Count <= 0 || this._needRefresh)
					{
						parametersNode.Nodes.Clear();

						var procdureName = procdureNode.Name;
						var procedureParameters = "ProcedureParameters";

						if(this.DataProvider.ProviderType == DataProviderType.MySql)
						{
							procedureParameters = "Procedure Parameters";
						}

						DataTable parametersTable = this.DataProvider.GetSchema(procedureParameters, new string[] { null, null, procdureName });
						DataView parametersView = parametersTable.DefaultView;
						parametersView.Sort = "ordinal_position";

						foreach(DataRowView dataRowView in parametersView)
						{
							string text = dataRowView["PARAMETER_NAME"] + " [" + dataRowView["DATA_TYPE"] + "," + dataRowView["CHARACTER_MAXIMUM_LENGTH"] + "," + dataRowView["PARAMETER_MODE"] + "]";

							var childNode = new TreeNode(text)
							{
								Name = dataRowView["PARAMETER_NAME"].ToString(),
								ImageKey = IMG_PROCEDURE_PARAMETER,
								SelectedImageKey = IMG_PROCEDURE_PARAMETER
							};

							parametersNode.Nodes.Add(childNode);
						}
					}
				}

				#endregion

				#region 函数参数

				if(e.Node.FirstNode.Name.Equals("function_parameter"))
				{
					var functionNode = e.Node;
					var parametersNode = functionNode.FirstNode;

					if(parametersNode.Nodes.Count <= 0 || this._needRefresh)
					{
						parametersNode.Nodes.Clear();

						DataTable parametersTable = null;
						var functionName = functionNode.Name;
						
						try
						{
							parametersTable = this.DataProvider.GetSchema("ProcedureParameters", new string[] { null, null, functionName });
						}
						catch(Exception ex)
						{
							if(this.DataProvider.ProviderType == DataProviderType.PostgreSQL)
							{
								MessageBox.Show("获取函数参数信息失败，请尝试手工执行下面地址的脚本：http://www.alberton.info/postgresql_meta_info.html ，脚本名称：public.function_args");
								Process.Start("http://www.alberton.info/postgresql_meta_info.html");
							}
							else
							{
								MessageBox.Show("获取函数参数信息失败：" + ex.Message);
							}
						}

						var parametersView = parametersTable.DefaultView;
						parametersView.Sort = "ordinal_position";
						parametersView.RowFilter = "IS_RESULT='NO'";

						foreach(DataRowView dataRowView in parametersView)
						{
							string text = dataRowView["PARAMETER_NAME"] + " [" + dataRowView["DATA_TYPE"] + "," + dataRowView["CHARACTER_MAXIMUM_LENGTH"] + "," + dataRowView["PARAMETER_MODE"] + "]";

							var childNode = new TreeNode(text)
							{
								Name = dataRowView["PARAMETER_NAME"].ToString(),
								ImageKey = IMG_FUNCTION_PARAMETER,
								SelectedImageKey = IMG_FUNCTION_PARAMETER
							};

							parametersNode.Nodes.Add(childNode);
						}

						// 返回结果
						var returnNode = functionNode.Nodes[1];
						var returnView = parametersTable.DefaultView;
						returnView.Sort = "ordinal_position";
						returnView.RowFilter = "IS_RESULT='YES'";

						returnNode.Nodes.Clear();

						foreach(DataRowView dataRowView in returnView)
						{
							string text = "return " + dataRowView["PARAMETER_NAME"] + " [" + dataRowView["DATA_TYPE"] + "," + dataRowView["CHARACTER_MAXIMUM_LENGTH"] + "," + dataRowView["PARAMETER_MODE"] + "]";

							var childNode = new TreeNode(text)
							{
								Name = dataRowView["PARAMETER_NAME"].ToString(),
								ImageKey = IMG_FUNCTION_PARAMETER,
								SelectedImageKey = IMG_FUNCTION_PARAMETER
							};

							returnNode.Nodes.Add(childNode);
						}

					}
				}

				#endregion
			}
		}

		/// <summary>
		/// 设置数据库连接字符。
		/// </summary>
		private void SetDbChar()
		{
			switch(_dataProviderType)
			{
				case "oracle":
					{
						_dbLeftChar = "\"";
						_dbRightChar = "\"";

						break;
					}
				case "oledb":
				case "odbc":
					{
						_dbLeftChar = "";
						_dbRightChar = "";

						break;
					}
				default:
					{
						_dbLeftChar = "[";
						_dbRightChar = "]";

						break;
					}
			}
		}

		#endregion
	}
}